//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

//#include <elasys_server.h>
#include <elapi.h>
#include <stdio.h>
#include <driver.h>
#include "gendev.h"

CGenDev::CGenDev()
{
    DevStub[0] = NULL;
    DevStub[1] = NULL;
    DevStub[2] = NULL;
    DevStub[3] = NULL;
    DevStub[4] = NULL;
    DevStub[5] = NULL;
    DevStub[6] = NULL;
    DevStub[7] = NULL;
    DevStub[8] = NULL;
    DevStub[9] = NULL;

    return ;
}

ECode CGenDev::Read(
    /* [in] */ Int64 u64Offset,
    /* [in] */ Int32 bytesToRead,
    /* [out] */ MemoryBuf * pBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CGenDev::Write(
    /* [in] */ Int64 u64Offset,
    /* [in] */ const MemoryBuf & buffer,
    /* [out] */ Int32 * pBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CGenDev::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ const MemoryBuf & inBuffer,
    /* [out] */ MemoryBuf * pOutBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    //High 16bits is Device Class ID
    //Lower 16bits is Control FuncNum
    int DevCls = (nControlCode >> 16) & 0xffff;
    int FunNum = (nControlCode & 0xffff);
#if defined(_DBGGENDEV)
    printf("Device class %d, Function Number %d\n", DevCls, FunNum);
#endif
    IDeviceDriver * pDevice = GetDriver(DevCls);
    if (NULL == pDevice) return E_ACCESS_DENIED;
    return pDevice->Control(FunNum, inBuffer, pOutBuffer, ppCompletionEvent);
}

static CGenDev *g_pGeneralDevice;

EXTERN IDeviceDriver * CDECL CreateGeneralDevice(uint_t uDeviceNo, void *pvParameter)
{
    g_pGeneralDevice = new CGenDev;
#if defined(_DBGGENDEV)
    printf("Create GeneralDevice 0x%08x\n", g_pGeneralDevice);
#endif
    IDeviceDriver *pDisplay;
    ECode ec = _CSystem_FindRunningObject(
            L"device:display0", (PInterface *)&pDisplay);
    if (SUCCEEDED(ec)) g_pGeneralDevice->DevStub[CLS2INX(CLS_Display)] = pDisplay;

    IDeviceDriver *pAudio;
    ec = _CSystem_FindRunningObject(
            L"device:wave0", (PInterface *)&pAudio);
    if (SUCCEEDED(ec)) g_pGeneralDevice->DevStub[CLS2INX(CLS_Audio)] = pAudio;

    IDeviceDriver *pTimer;
    ec = _CSystem_FindRunningObject(
            L"device:timer0", (PInterface *)&pTimer);
    if (SUCCEEDED(ec)) g_pGeneralDevice->DevStub[CLS2INX(CLS_Timer)] = pTimer;

    return (IDeviceDriver *)g_pGeneralDevice;
}
